package com.akuhome.resource.service.check;

import com.akuhome.resource.DO.RoomType;
import com.akuhome.resource.DO.check.AccCheck;
import com.akuhome.resource.DO.check.ClassroomCheck;
import com.akuhome.resource.DO.check.FoodCheck;
import com.akuhome.resource.DO.check.use.ClassroomUse;
import com.akuhome.resource.DO.check.use.DormitoryUse;
import com.akuhome.resource.DO.check.use.FoodActual;
import com.akuhome.resource.DO.need.*;
import com.akuhome.resource.entity.Build;
import com.akuhome.resource.service.entity.ClassroomService;
import com.akuhome.resource.service.entity.DormitoryService;
import com.akuhome.resource.service.need.AccNeedService;
import com.akuhome.resource.service.need.ClassroomNeedService;
import com.akuhome.resource.service.need.FoodNeedService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class ProjectCheckService {

//    private final Logger logger = LoggerFactory.getLogger(ProjectCheckService.class);

    @Autowired
    AccCheckService accCheckService;
    @Autowired
    DormitoryService dormitoryService;
    @Autowired
    ClassroomCheckService classroomCheckService;
    @Autowired
    FoodCheckService foodCheckService;
    @Autowired
    AccNeedService accNeedService;
    @Autowired
    ClassroomNeedService classroomNeedService;
    @Autowired
    FoodNeedService foodNeedService;
    @Autowired
    ClassroomService classroomService;

    Map<Build,Map<RoomType,Double>> priceMap;
    Map<Integer,String> classroomNameMap;

    @Transactional
    public void initCheck(String uid){
//        logger.info("为项目uid为 "+uid+" 的项目添加结算报表开始");
        initPriceMap();
        initClassroomName();
        AccNeed accNeed = accNeedService.findNeedByProjectUid(uid);
        insertAccCheck(accNeed,uid);
        insertFoodCheck(uid);
        ClassroomNeed classroomNeed = classroomNeedService.findNeedByProjectUid(uid);
        insertClassroomCheck(classroomNeed,uid);
    }

    private void insertAccCheck(AccNeed accNeed,String uid){
        AccCheck accCheck = accNeedToAccCheck(accNeed);
        accCheckService.insertAccCheck(accCheck,uid);
        List<DormitoryUse> useList = accNeedDetailToDormitoryUse(accNeed.getDetailList(),accCheck.getId());
        accCheckService.insertDormitoryUseList(useList);
    }

    private void insertFoodCheck(String uid){
        foodCheckService.insertFoodCheck(new FoodCheck(),uid);
    }

    private void insertClassroomCheck(ClassroomNeed classroomNeed,String uid){
        ClassroomCheck classroomCheck = classroomNeedToClassroomCheck(classroomNeed);
        classroomCheckService.insertClassroomCheck(classroomCheck,uid);
        List<ClassroomUse> useList = classroomNeedDetailToClassroomUse(classroomNeed.getDetailList(),classroomCheck.getId());
        classroomCheckService.insertClassroomUse(useList);
    }

    private void initPriceMap(){
        priceMap = new HashMap<>();
        dormitoryService.findAllDormitory().forEach((dormitory -> {
            Build build = dormitory.getBuild();
            RoomType roomType = dormitory.getRoomType();
            if(priceMap.containsKey(build)){
                if(priceMap.get(build).containsKey(roomType)){
                    priceMap.get(build).put(roomType,priceMap.get(build).get(roomType)+dormitory.getFullPrice());
                }else{
                    priceMap.get(build).put(roomType,dormitory.getFullPrice());
                }
            }else{
                HashMap<RoomType,Double> map = new HashMap<>();
                map.put(roomType,dormitory.getFullPrice());
                priceMap.put(build,map);
            }
        }));
    }

    private void initClassroomName(){
        classroomNameMap = new HashMap<>();
        classroomService.findAllClassroom().forEach((classroom -> {
            classroomNameMap.put(classroom.getId(),classroom.getName());
        }));
    }

    private AccCheck accNeedToAccCheck(AccNeed accNeed){
        List<AccNeedDetail> detailList = accNeed.getDetailList();
        Integer sum = 0;
        for(AccNeedDetail detail: detailList){
            sum += detail.getAmount();
        }
        return  new AccCheck(sum,new Date());
    }

    private List<DormitoryUse> accNeedDetailToDormitoryUse(List<AccNeedDetail> detailList,Integer accCheckId){
        List<DormitoryUse> useList = new ArrayList<>();
        Map<Build,Map<RoomType,Integer>> usageMap = new HashMap<>();
        detailList.forEach((detail)->{
            Build build = detail.getBuild();
            RoomType roomType = detail.getRoomType();
            if(usageMap.containsKey(build)){
                if(usageMap.get(build).containsKey(roomType)){
                    usageMap.get(build).put(roomType,usageMap.get(build).get(roomType)+detail.getAmount()); 
                }else{
                    usageMap.get(build).put(roomType,detail.getAmount());
                }
            }else{
                HashMap<RoomType,Integer> map = new HashMap<>();
                map.put(roomType,detail.getAmount());
                usageMap.put(build,map);
            }
        });
        
        for(Map.Entry<Build,Map<RoomType,Integer>> b :usageMap.entrySet()){
            for(Map.Entry<RoomType,Integer> r:b.getValue().entrySet()){
                DormitoryUse dormitoryUse = new DormitoryUse();
                dormitoryUse.setBuild(b.getKey().getName());
                dormitoryUse.setRoomType(r.getKey().getName());
                dormitoryUse.setUsage(r.getValue().toString());
                Double standard = priceMap.get(b.getKey()).get(r.getKey());
                Integer use = r.getValue();
                dormitoryUse.setPrice(standard*use);
                dormitoryUse.setStandard(standard.toString());
                dormitoryUse.setAccCheckId(accCheckId);
                useList.add(dormitoryUse);
            }
        }
        return useList;
    }

    private ClassroomCheck classroomNeedToClassroomCheck(ClassroomNeed classNeed){
        return new ClassroomCheck(Integer.toString(classNeed.getDetailList().size()),new Date());
    }

    private List<ClassroomUse> classroomNeedDetailToClassroomUse(List<ClassroomNeedDetail> detailList,Integer checkId){
        List<ClassroomUse> useList = new ArrayList<>();
        Map<Integer,Integer> usageMap = new HashMap<>();
        for(ClassroomNeedDetail detail: detailList){
            Integer id = detail.getClassroomId();
            if(usageMap.containsKey(id)){
                usageMap.put(id,usageMap.get(id)+1);
            }else{
                usageMap.put(id,1);
            }
        }
        for(Map.Entry<Integer,Integer> entry:usageMap.entrySet()){
            ClassroomUse use = new ClassroomUse();
            use.setName(classroomNameMap.get(entry.getKey()));
            use.setTimes(entry.getValue().toString());
            use.setClassroomCheckId(checkId);
            useList.add(use);
        }
        return useList;
    }
}
